package cn.tedu.order.tx;

import cn.tedu.order.entity.Order;
import cn.tedu.order.entity.TxInfo;
import cn.tedu.order.feign.EasyIdClient;
import cn.tedu.order.mapper.OrderMapper;
import cn.tedu.order.mapper.TxMapper;
import cn.tedu.order.util.JsonUtil;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component
@RocketMQTransactionListener
public class TxListener implements RocketMQLocalTransactionListener {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private TxMapper txMapper;
    @Autowired
    private EasyIdClient easyIdClient;
    // 执行本地事务，存储订单
    @Transactional
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object o) {
        RocketMQLocalTransactionState state = null; //用来返回
        int status = 0; //用来存储
        try {
            Order order = (Order) o;
            String s = easyIdClient.nextId("order_business");
            Long orderId = Long.valueOf(s);
            order.setId(orderId);
            orderMapper.create(order);
            // if (Math.random() < 0.8) {
            //     throw new RuntimeException("模拟异常");
            // }
            // 成功
            state = RocketMQLocalTransactionState.COMMIT;
            status = 0;
        } catch (Exception e) {
            // 失败
            state = RocketMQLocalTransactionState.ROLLBACK;
            status = 1;
        }

        String json = new String((byte[]) message.getPayload()); // AccountMessage - {xid, userId, money}
        String xid = JsonUtil.getString(json, "xid");
        txMapper.insert(new TxInfo(xid, status, ""+System.currentTimeMillis()));

        return state;
    }

    // 处理事务状态回查
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        String json = new String((byte[]) message.getPayload()); // AccountMessage - {xid, userId, money}
        String xid = JsonUtil.getString(json, "xid");

        TxInfo txInfo = txMapper.selectById(xid);
        if (txInfo == null) {
            return RocketMQLocalTransactionState.UNKNOWN;
        }

        switch (txInfo.getStatus()) {
            case 0: return RocketMQLocalTransactionState.COMMIT;
            case 1: return RocketMQLocalTransactionState.ROLLBACK;
            default: return RocketMQLocalTransactionState.UNKNOWN;
        }
    }
}